//#include "Freenove_WS2812_Lib_for_ESP32.h"

#include <Adafruit_NeoPixel.h>//关键是这个库
#include <string>

#include "lattice.h"
#include "lib/images.h"
#include "lib/cache.h"
#include "lib/strSplit.h"

#define WS_PIN  13	//定义选择引脚
#define WS_NUM  256	//定义led个数，决定数组长度

Adafruit_NeoPixel pixels(WS_NUM, WS_PIN, NEO_GRB + NEO_KHZ800);//第一个参数led个数，第二个引脚号，第三个rgb模式，第四个800khz-ws2812

uint32_t color = Adafruit_NeoPixel::Color(0, 0, 0);
uint32_t low = Adafruit_NeoPixel::Color(0, 0, 0);
uint32_t tempColor = Adafruit_NeoPixel::Color(0, 0, 0);
bool isTempColor = false;

//眨眼动作
int isZy = -1; //为0开始眨眼
int zyArr[] = {2,4,6,4,2,0};
void zhaYan(int index, int level) {

    uint32_t _color = isTempColor ? tempColor: color;

    int tag = 0;
    for (int i = 0; i < WS_NUM -8; i+=8) {
        unsigned short int* image = getImage(index);

        if(i%8 == 0) tag++;


        for(int l = 0; l< 8; l++){
            int in = i+ l;
            bool lamp = image[in] == 1;

            if(tag%2 == 0) {
                if(l> 7 - level) lamp = false;
                pixels.setPixelColor(in, lamp ? _color : low);
            }else{
                if(l< level) lamp = false;
                pixels.setPixelColor(in, lamp ? _color : low);
            }
        }
    }
    pixels.show();//刷新
}

void viewImage(int index)
{
    uint32_t _color = isTempColor ? tempColor : color;

    for (int i = 0; i < WS_NUM; i++) {
        unsigned short int* image = getImage(index);

        bool lamp = image[i] == 1;

//                pixels.setPixelColor(i, pixels.Color(lamp ? 10 : 0, lamp ? 0 : 0, lamp ? 0 : 0));
        pixels.setPixelColor(i, lamp?_color:low);//注意是从0开始，第一个led对应0
    }
    pixels.show();//刷新
}

void ledInit() {
    /***WS2812******/
    pixels.begin();//初始化灯带
    pixels.clear();//清空灯带数组
    /***WS2812******/

    //初始化LED颜色
    String rgb = getCache("led_color");
    char** arr = strSplit(rgb.c_str(), ',');
    setColor(std::stoi(arr[0]), std::stoi(arr[1]), std::stoi(arr[2]), false);

    zhaYan(0, 6);
    zhaYan(0, 4);
    zhaYan(0, 2);
    zhaYan(0, 0);
}

unsigned int animation[][15][3] = {
        {
                {0, 800},
                {3, 800},
                {0, 1500},
                {100, 1, 5}, //50%几率眨眼
                {5, 1000},
                {2, 800},
                {1, 1500},
                {2, 800},
                {100, 2, 3}, //30%几率眨眼
                {1, 800},
                {2, 1500},
                {4, 2000},
                {2, 1500},
                {100, 1, 5}, //50%几率眨眼
                {1, 1500}
        },
        { //白眼
                {6, 1000},
                {7, 1000},
                {6, 500},
                {7, 500},
                {6, 1000},
                {7, 1000},
                {6, 500},
                {7, 500},
                {6, 1000},
                {7, 1000},
                {6, 500},
                {7, 500},
        },
        { //左转
                {8, 1000},
        },
        { //右转
                {9, 1000},
        },
        { //加速
                {11, 1000},
        },
        { //减速
                {12, 1000},
        },
        { //新手上路
                {10, 36000000}
        },
        { //关远光
                {17, 100},
                {16, 100},
                {17, 100},
                {16, 100},
                {17, 100},
                {16, 100},
                {13, 800},
                {14, 800},
                {13, 800},
                {14, 800},
                {15, 4000},
        }
};

//动画组的长度
short taskLens[] = {
        15,
        12,
        1,
        1,
        1,
        1,
        7,
        11
};

int task = 0; //当前任务
int taskIndex = 0; //当前任务进度
int taskLevel = 0; //当前任务进度
long runTime = 0; //执行动画时间

void doneTask() {
    isTempColor = false;
    task = 0;
    taskIndex = 0;
    taskLevel = 0;
    runTime = millis();
}

void ledLoop() {
    long time = millis();

    if(time > runTime){
        if(isZy > -1){
            if(isZy > 5){
                isZy = -1;
                taskIndex++;//下一个画面
                viewImage(animation[task][taskIndex][0]);
                runTime = time+ animation[task][taskIndex][1]; //下一次任务
            }else{
                int s = animation[task][taskIndex][1];
                zhaYan(s, zyArr[isZy++]);
                runTime = time+ 50;
            }
            return;
        }

        if(taskIndex >= taskLens[task]){
            //动画结束
            return doneTask();
        }

        int rand = animation[task][taskIndex][2];
        //计算随机值
        if(rand == 0 || rand > 0 && rand < random(10)){
            short imgIndex = animation[task][taskIndex][0];
            //显示图像
            if(imgIndex == 100){ //眨眼
                isZy = 0;
            }else{
                viewImage(imgIndex);
                runTime = time+ animation[task][taskIndex][1]; //下一次任务
                taskIndex++;
            }
        }else{
            runTime = time+ animation[task][taskIndex][1]; //下一次任务
        }
    }
}

void setColor(int r, int g, int b, bool isTemp) {
    if(isTemp){
        tempColor = Adafruit_NeoPixel::Color(r, g, b);
        isTempColor = true;
    }else{
        color = Adafruit_NeoPixel::Color(r, g, b);
    }
}

//设置播放动画
void setAnimation(int index, int level) {
    if(taskLevel > level){
        return; //有更高等级的任务在进行
    }
    task = index;
    taskIndex = 0;
    taskLevel = level;
    runTime = millis();
}
